/**
 * 
 * Praktikum CG WP WS13/14
 * Gruppe: Andreas Rebri(andreas.rebri@haw-hamburg.de)
 * 		   Joschka Schulz(joschka.schulz@haw-hamburg.de)
 * Aufgabe : Aufgabenblatt 6
 * Verwendete Quellen: -
 */
package cg6;

import javax.vecmath.Vector3d;

/**
 * A implementation of the hermite curve.
 */
public class HermiteCurve implements ICurve {

	/**
	 * a list of control points for the hermite curve
	 */
	Vector3d[] controlPoints;
	
	/**
	 * The standard constructor with four vectors
	 * 
	 * @param v1 the start vector of the curve
	 * @param v2 the first control point
	 * @param v3 the second control point
	 * @param v4 the end vector of the curve
	 */
	public HermiteCurve(Vector3d v1, Vector3d v2, Vector3d v3, Vector3d v4) {
		controlPoints = new Vector3d[] {v1, v2, v3, v4};
	}
	
	/**
	 * A holder method for the different methods of the cubic hermite curve
	 * 
	 * @param i the number of the needed function
	 * @param t the position of the curve
	 * @return returns a double that is used for eval method
	 */
	private double evalBasisFunction(int i, double t) {
		switch(i) {
			case 0:
				return ((1-t)*(1-t))*(1+(2*t));
			case 1:
				return t*((1-t)*(1-t));
			case 2:
				return -t*-t*(1-t);
			case 3:
				return (3-(2*t))*(t*t);
			default:
				return 0;
		}
	}
	
	/**
	 * the derivation of the hermite curve.
	 * 
	 * @param i the number of the needed function
	 * @param t the position of the curve
	 * @return returns the derivative of the eval method
	 */
	private double evalDerivative(int i, double t) {
		switch(i) {
			case 0:
				return 6*(-1+t)*t;
			case 1:
				return 1-4*t+(3*(t*t));
			case 2:
				return (2-3*t)*t;
			case 3:
				return -6*(-1+t)*t;
			default:
				return 0;
		}
	}
	
	@Override
	public Vector3d eval(double t) {
		Vector3d result = new Vector3d();
		
		Vector3d tmp;
		for(int i = 0; i < 4; i++) {
			tmp = new Vector3d(controlPoints[i]);
			tmp.scale(evalBasisFunction(i, t));
			result.add(tmp);
		}
		
		return result;
	}

	@Override
	public Vector3d derivative(double t) {
		Vector3d result = new Vector3d();
		
		Vector3d tmp;
		for(int i = 0; i < 4; i++) {
			tmp = new Vector3d(controlPoints[i]);
			tmp.scale(evalDerivative(i, t));
			result.add(tmp);
		}
		
		return result;
	}


}
